package com.gitee.wsl.evaluator.token


abstract class AbstractToken<T>(
    override var lexeme: String? = null,
    override val lineNo: Int,
    override val startIndex: Int,
    override var metaMap: MutableMap<String, Any?>? = null
) : Token<T> {

     override fun withMeta(
        name: String,
        v: Any?,
    ): Token<T>? {
        if (this.metaMap == null) {
            this.metaMap = mutableMapOf()
        }
        this.metaMap!![name] = v
        return this
    }


     override fun <V> getMeta(name: String, defaultVal: V?): V? {
        if (this.metaMap == null) {
            return defaultVal
        }
        val value= this.metaMap!![name] as V? ?: return defaultVal
         return value
    }

     override fun <V> getMeta(name: String): V? {
        if (this.metaMap == null) {
            return null
        }
        return this.metaMap!![name] as V?
    }


    override val endIndex: Int
        get() = this.lineNo + (if (this.lexeme != null) this.lexeme!!.length else 0)


     override fun toString(): String {
        return ("[type='" + type.name + "',lexeme='" + lexeme + "',index=" + this.lineNo + "]")
    }


     override fun hashCode(): Int {
        val prime: Int = 31
        var result: Int = 1
        result = prime * result + (if ((this.lexeme == null)) 0 else this.lexeme.hashCode())
        result = prime * result + this.lineNo
        return result
    }


     override fun equals(obj: Any?): Boolean {
        if (this === obj) {
            return true
        }
        if (obj == null) {
            return false
        }
        if (this::class != obj::class) {
            return false
        }
        val other: AbstractToken<*>? = obj as AbstractToken<*>?
        if (this.lexeme == null) {
            if (other?.lexeme != null) {
                return false
            }
        } else if (this.lexeme != other?.lexeme) {
            return false
        }
        if (this.lineNo != other?.lineNo) {
            return false
        }
        return true
    }
}
